package dao;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import domain.Vocabulary;

public class VocabularyDAO extends GenericDAO<Vocabulary> {
	public static final String TABLE_NAME = "vocabulario";
	private Vocabulary vocabulary;

	public VocabularyDAO() throws ClassNotFoundException, IOException {
		super();
		table = TABLE_NAME;
	}

	@Override
	/*
	 * Inserts a vocabulary in the database
	 * @param value, the vocabulary to insert
	 */
	protected void onInsert(Vocabulary value) throws SQLException {
		query = new StringBuilder("");
		vocabulary = value;
		query.append("insert into ");
		query.append(table);
		query.append(" values (?,?,?,?)");
		Connection conn = getConnection(); 
		statement = conn.prepareStatement(query.toString());
		statement.setInt(1, 0);
		statement.setString(2, vocabulary.getWord());
		statement.setInt(3, vocabulary.getMaxFrequency());
		statement.setInt(4, vocabulary.getPostList().size());
		statement.executeUpdate();
		closeConnection(conn);
		VocabularyCache.getInstance().clear();
	}

	@Override
	public int count() throws SQLException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	/*
	 * Selects a vocabulary from the database, which match with the id given
	 * @param id, the id of the vocabulary to get
	 * @return voc, the vocabulary with the id given by parameter
	 */
	protected Vocabulary onSelect(Integer id) throws SQLException {
		VocabularyCache cache = VocabularyCache.getInstance();
		Vocabulary voc = cache.find(id);
		if (voc != null) {
			return voc;
		}
		query = new StringBuilder("");
		query.append("select id_vocabulario, termino, frecuencia_maxima, size_lista_posteo from ");
		query.append(table);
		query.append(" where id_vocabulario = ?");
		Connection conn = getConnection(); 
		statement = conn.prepareStatement(query.toString());
		statement.setInt(1, id);
		rs = statement.executeQuery();
		if (rs.next()) {
			voc = new Vocabulary();
			voc.setId(rs.getInt(1));
			voc.setWord(rs.getString(2));
			voc.setMaxFrequency(rs.getInt(3));
			voc.setPostListSize(rs.getInt(4));
		}
		
		closeConnection(conn);
		cache.putIn(id, voc);
		return voc;
	}

	@Override
	/*
	 * Selects the vocabularies from the database, which match with the attributes of the
	 * vocabulary given
	 * @param value, the vocabulary with the attributes with which must match the
	 * collection of vocabularies returned
	 * @return collection, a collection of vocabularies
	 */
	protected List<Vocabulary> onSelect(Vocabulary value) throws SQLException {
		VocabularyListCache cache = VocabularyListCache.getInstance();
		List<Vocabulary> collection = cache.find(value);
		if (collection == null) {
			collection = new ArrayList<Vocabulary>();
			Vocabulary voc = null;
			query = new StringBuilder("");
			query.append("select id_vocabulario, termino, frecuencia_maxima, size_lista_posteo from ");
			query.append(table);
			Connection conn = getConnection();
			if (value != null) {
				prepareUpdateQuery(conn, value, query);
			}
			else {
				statement = conn.prepareStatement(query.toString());
			}
			rs = statement.executeQuery();
			while (rs.next()) {
				voc = new Vocabulary();
				voc.setId(rs.getInt(1));
				voc.setWord(rs.getString(2));
				voc.setMaxFrequency(rs.getInt(3));
				voc.setPostListSize(rs.getInt(4));
				collection.add(voc);
			}
			
			closeConnection(conn);
		}
		cache.putIn(value, collection);
		return collection;
	}

	@Override
	/*
	 * Updates a vocabulary in the database, with the values of the vocabulary passed by
	 * parameter
	 * @param value, the vocabulary to update
	 */
	protected void onUpdate(Vocabulary value) throws SQLException {
		query = new StringBuilder("");
		query.append("update ");
		query.append(table);
		query.append(" set termino=?, frecuencia_maxima=?, size_lista_posteo=?");
		query.append(" where id_vocabulario=?");
		Connection conn = getConnection(); 
		statement = conn.prepareStatement(query.toString());
		statement.setString(1, value.getWord());
		statement.setInt(2, value.getMaxFrequency());
		statement.setInt(3, value.getPostList().size());
		statement.setInt(4, value.getId());
		statement.executeUpdate();
		
		closeConnection(conn);
		VocabularyCache.getInstance().clear();
	}

	/**
	 * prepares the query and the statement according with the non null values of the
	 * document given by parameter
	 * @param value, the document with the attributes used to build the filter
	 * @param statement, the statement to perform the query
	 * @param query, the query string
	 * @throws SQLException
	 */
	protected final void prepareUpdateQuery(Connection conn, Vocabulary value, 
			StringBuilder query) throws SQLException {
		String auxQuery = "";
		List<String> dbColumns = new ArrayList<String>();
		List<Object> index = new ArrayList<Object>();
		if (value.getId() != null) {
			dbColumns.add("id_vocabulario");
			index.add(value.getId());
		}
		if (value.getWord() != null) {
			dbColumns.add("termino");
			index.add(value.getWord());
		}
		if (value.getMaxFrequency() != null) {
			dbColumns.add("frecuencia_maxima");
			index.add(value.getMaxFrequency());
		}
		if (value.getPostList().size() != 0) {
			dbColumns.add("size_lista_posteo");
			index.add(value.getPostList().size());
		}
		if (dbColumns.size() > 0) {
			auxQuery = " where " + dbColumns.get(0).toString() + "=?";
			for (int i = 1; i < dbColumns.size(); i++) {
				auxQuery += " and " + dbColumns.get(i).toString() + "=?";
			}
		}
		query.append(auxQuery);
		this.statement = conn.prepareStatement(query.toString());
		prepareUpdateStatement(index);
	}
}
